<template>
  <Spin :spinning="spinning">
    <BasicTree
      title=""
      toolbar
      search
      draggable
      :clickRowToExpand="false"
      :treeData="treeData"
      :selectedKeys="selectedKeys"
      @select="handleSelect"
      @drop="handleDrop"
      treeKey="code"
      :expandedKeys="expandedKeys"
    >
      <template #title="{ key, title, code, layer, isOpen, type, formCode }">
        <Dropdown
          :trigger="['contextmenu']"
          @visible-change="
            (visible) => visibleChange(visible, { key, title, code, layer, formCode, type })
          "
        >
          <div class="w-full" :class="{ 'text-gray-400': !isOpen }">{{ title }}</div>
          <template #overlay>
            <Menu
              @click="
                ({ key: menuKey }) => onContextMenuClick(menuKey, { key, title, code, layer, type })
              "
            >
              <MenuItem key="1"
                ><Icon
                  icon="ant-design:plus-outlined"
                  style="color: blue"
                  class="mr-2"
                />添加</MenuItem
              >
              <MenuItem key="2">
                <Icon icon="ant-design:edit-outlined" style="color: blue" class="mr-2" />修改
              </MenuItem>
              <Popconfirm
                placement="top"
                title="确定要删除吗？"
                ok-text="确定"
                cancel-text="取消"
                @confirm="delAction(key)"
              >
                <MenuItem key="3">
                  <Icon icon="ant-design:delete-filled" style="color: red" class="mr-2" />删除
                </MenuItem>
              </Popconfirm>
              <MenuItem key="4" v-if="type != 1">
                <Icon icon="ant-design:bug-outlined" class="mr-2" />调试模式
              </MenuItem>
              <MenuItem key="5" v-if="type != 1">
                <Icon icon="ant-design:check-outlined" class="mr-2" />正常模式
              </MenuItem>
            </Menu>
          </template>
        </Dropdown>
      </template>
    </BasicTree>
  </Spin>
</template>
<script lang="ts">
  import { defineComponent, onMounted, ref, unref } from 'vue';
  import { Spin, Popconfirm, Dropdown, Menu } from 'ant-design-vue';
  import { BasicTree, TreeItem } from '/@/components/Tree';
  import {
    getFlowGetDirTreeAll,
    getAdminFlowMoveNode,
    getAdminFlowDelNode,
    getAdminSetDebugMode,
  } from '/@/api/flowManage/flowManage';
  import Icon from '/@/components/Icon';
  import { useMessage } from '/@/hooks/web/useMessage';
  import { useRouter } from 'vue-router';
  import { isArray } from '/@/utils/is';
  export default defineComponent({
    name: 'DeptTree',
    components: { BasicTree, Spin, Popconfirm, Dropdown, Menu, MenuItem: Menu.Item, Icon },

    emits: [
      'select',
      'drop',
      'addAction',
      'delAction',
      'ok',
      'treeContextMenu',
      'editAction',
      'rootRecord',
    ],
    setup(_, { emit }) {
      const { createMessage } = useMessage();
      const treeData = ref<TreeItem[]>([]);
      let spinning = ref(false);
      let selectedKeys = ref<String[]>([]);
      let expandedKeys = ref<String[]>([]);
      const rootRecord = ref<Recordable>({});
      const dataListKey = ref<Recordable[]>([]);
      const { currentRoute } = useRouter();
      async function fetch(isReloadByUpdate = false) {
        treeData.value = (await getFlowGetDirTreeAll()) || [];
        treeData.value = setChildren(treeData.value);
        rootRecord.value = {};
        if (treeData.value.length) {
          const { query } = unref(currentRoute);
          if (query?.typeCode) {
            rootRecord.value = getCurrentData(unref(treeData), query.typeCode);
            console.log('rootRecord', rootRecord.value);
          } else {
            rootRecord.value = treeData.value[0];
          }
          if (!isReloadByUpdate) {
            // 当对节点操作更新后，不再emit，以免在事件中isRootNodeShowBySubUnitUser被置为root，致子单位管理员看到的页面为空
            emit('rootRecord', unref(rootRecord).code);
          }
          if (selectedKeys.value.length === 0) {
            selectedKeys.value = [unref(rootRecord).code];
            emit('treeContextMenu', rootRecord.value);
          }
          if (expandedKeys.value.length === 0) {
            const keys: any = unref(dataListKey)
              .map((item) => {
                if (item.key == unref(rootRecord).code) {
                  return getParentKey(item.key, unref(treeData));
                }
                return null;
              })
              .filter((item, i, self) => item && self.indexOf(item) === i);
            if (!keys.includes(treeData.value[0].code)) {
              keys.push(treeData.value[0].code);
            }
            expandedKeys.value = keys;
          }
        }
      }

      //获取当前父节点
      function getParentKey(key, tree) {
        let parentKey;
        let temp;
        for (let i = 0; i < tree.length; i++) {
          const node = tree[i];
          if (node.children) {
            if (node.children.some((item) => item.key === key)) {
              parentKey = node.key;
            } else if ((temp = getParentKey(key, node.children))) {
              parentKey = temp;
            }
          }
        }
        return parentKey;
      }

      function getCurrentData(data, code) {
        for (let item of data) {
          if (item.code == code) {
            return item;
          } else if (isArray(item.children) && item.children.length) {
            let res = getCurrentData(item.children, code);
            if (res) {
              return res;
            }
          }
        }
      }

      function setChildren(node) {
        node.forEach((item) => {
          item.key = item.code;
          item.title = item.name;

          dataListKey.value.push({ key: item.code, title: item.name });
          if (item.children && Array.isArray(item.children) && item.children.length > 0) {
            item.isLeaf = false;
            setChildren(item.children);
          } else {
            item.isLeaf = true;
          }
        });
        return node;
      }

      function handleSelect(keys, trc) {
        console.log('handleSelect trc', trc);
        // 检查是否为右键点击（button 2 表示右键）
        if (trc.nativeEvent.button === 2) return;
        selectedKeys.value = [trc.node.dataRef.code];
        emit('select', keys[0], trc);
      }

      function handleDrop({ dropPosition }, current, currentParent, data) {
        // if (current.parentCode != currentParent.code) {
        //   createMessage.warning('层级不一致，不能拖动！');
        //   fetch();
        //   return;
        // }
        let params = {
          code: current.code,
          parent_code: currentParent.code,
          position: dropPosition,
        };
        spinning.value = true;
        getAdminFlowMoveNode(params)
          .then(() => {
            treeData.value = [];
            fetch();
            emit('ok', 1);
            spinning.value = false;
          })
          .catch(() => {
            spinning.value = false;
          });
        emit('drop', dropPosition, current, currentParent, data);
      }

      const addAction = (treeKey, { layer }) => {
        if (layer - 0 >= 3) {
          createMessage.warning('流程类型层级不能超过两层');
          return;
        }
        emit('addAction', treeKey);
      };
      const editAction = (treeKey) => {
        emit('editAction', treeKey);
      };
      const delAction = async (code) => {
        // emit('delAction', treeKey);
        let result = await getAdminFlowDelNode({ code });
        selectedKeys.value = [rootRecord.value.code];
        emit('treeContextMenu', rootRecord.value);
        fetch();
        return result;
      };
      const debugAction = async (record, isDebug) => {
        await getAdminSetDebugMode({ code: record.key, isDebug });
        createMessage.success(`${record.title} 已置为${isDebug ? '调试模式' : '正常模式'}`);
      };

      const onContextMenuClick = (menuKey: string, record: Record) => {
        switch (menuKey) {
          case '1':
            addAction(record.key, record);
            break;
          case '2':
            editAction(record.key);
            break;
          case '3':
            delAction(record.key);
            break;
          case '4':
            debugAction(record, true);
            break;
          case '5':
            debugAction(record, false);
            break;
        }
      };

      const visibleChange = (visible: boolean, record: Record) => {
        if (visible) {
          selectedKeys.value = [record.code];
          emit('treeContextMenu', record);
        }
      };

      onMounted(() => {
        fetch();
      });
      return {
        treeData,
        handleSelect,
        handleDrop,
        fetch,
        addAction,
        delAction,
        selectedKeys,
        spinning,
        expandedKeys,
        onContextMenuClick,
        visibleChange,
      };
    },
  });
</script>
